﻿using System;
using System.Collections.Generic;
using System.Dynamic;
using System.IO;
using System.Security.AccessControl;
using System.Security.Cryptography;
using System.Text;
using System.Web;

namespace PageAdmin.Utils
{

    /// <summary>
    /// 涉及文件或目录操作帮助类
    /// </summary>
    public class IOHelper
    {
        #region 基础方法

        /// <summary>
        /// 路径转为绝对路径
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static string MapPath(string path)
        {
            if (string.IsNullOrEmpty(path))
            {
                return null;
            }
            else
            {
                path = Path.Combine(path);
            }
            if (path.Contains(":"))
            {
                return path;
            }
            else
            {
                path = path.Replace("//", "/");
                path = path.Replace("/", "\\");
                if (path.IndexOf("/") == 0 || path.IndexOf("\\") == 0)
                {
                    path = path.Substring(1, path.Length - 1);
                }
                return StringHelper.Combine(AppDomain.CurrentDomain.BaseDirectory, path);
            }
        }

        /// <summary>
        /// 文件转base64
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static string FileToBase64(string filePath)
        {
            filePath = MapPath(filePath);
            FileStream fileStream = File.Open(filePath, FileMode.Open);
            byte[] buffer = new byte[fileStream.Length];
            fileStream.Read(buffer, 0, buffer.Length);
            fileStream.Close();
            return Convert.ToBase64String(buffer);
        }


        /// <summary>
        /// base64字符串保存为文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="stringBase64"></param>
        public static void Base64ToFile(string filePath, string stringBase64)
        {
            filePath = MapPath(filePath);
            FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate);
            byte[] buffer = Convert.FromBase64String(stringBase64);
            fileStream.Write(buffer, 0, buffer.Length);
            fileStream.Close();
        }

        /// <summary>
        /// 获取文件的MD5码
        /// </summary>
        /// <param name="fileName">传入的文件名（含路径及后缀名）</param>
        /// <returns></returns>
        public static string GetFileMD5(string fileName)
        {
            try
            {
                using (FileStream file = new FileStream(fileName, System.IO.FileMode.Open))
                {
                    MD5 md5 = new MD5CryptoServiceProvider();
                    byte[] retVal = md5.ComputeHash(file);
                    file.Close();
                    StringBuilder sb = new StringBuilder();
                    for (int i = 0; i < retVal.Length; i++)
                    {
                        sb.Append(retVal[i].ToString("x2"));
                    }
                    return sb.ToString();
                }
            }
            catch (Exception ex)
            {
                throw new Exception("GetFileMD5 fail,error:" + ex.Message);
            }
        }

        /// <summary>
        /// 根据后缀获取文件对应的ContentType
        /// </summary>
        /// <param name="filenameExtension"></param>
        /// <returns></returns>
        public static string GetContentType(string filenameExtension)
        {
            filenameExtension = filenameExtension.ToLower().Replace(".","");
            Dictionary<string, string> dictionary = new Dictionary<string, string>()
            {
        {"xlsx","application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
        {"xltx","application/vnd.openxmlformats-officedocument.spreadsheetml.template"},
        {"potx","application/vnd.openxmlformats-officedocument.presentationml.template"},
        {"ppsx","application/vnd.openxmlformats-officedocument.presentationml.slideshow"},
        {"pptx","application/vnd.openxmlformats-officedocument.presentationml.presentation"},
        {"sldx","application/vnd.openxmlformats-officedocument.presentationml.slide"},
        {"docx","application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
        {"dotx","application/vnd.openxmlformats-officedocument.wordprocessingml.template"},
        {"xlam","application/vnd.ms-excel.addin.macroEnabled.12"},
        {"xlsb","application/vnd.ms-excel.sheet.binary.macroEnabled.12"},
        {"apk","application/vnd.android.package-archive"},
        {"hqx","application/mac-binhex40"},
        {"cpt","application/mac-compactpro"},
        {"doc","application/msword"},
        {"ogg","audio/ogg"},
        {"pdf","application/pdf"},
        {"rtf","text/rtf"},
        {"mif","application/vnd.mif"},
        {"xls","application/vnd.ms-excel"},
        {"ppt","application/vnd.ms-powerpoint"},
        {"odc","application/vnd.oasis.opendocument.chart"},
        {"odb","application/vnd.oasis.opendocument.database"},
        {"odf","application/vnd.oasis.opendocument.formula"},
        {"odg","application/vnd.oasis.opendocument.graphics"},
        {"otg","application/vnd.oasis.opendocument.graphics-template"},
        {"odi","application/vnd.oasis.opendocument.image"},
        {"odp","application/vnd.oasis.opendocument.presentation"},
        {"otp","application/vnd.oasis.opendocument.presentation-template"},
        {"ods","application/vnd.oasis.opendocument.spreadsheet"},
        {"ots","application/vnd.oasis.opendocument.spreadsheet-template"},
        {"odt","application/vnd.oasis.opendocument.text"},
        {"odm","application/vnd.oasis.opendocument.text-master"},
        {"ott","application/vnd.oasis.opendocument.text-template"},
        {"oth","application/vnd.oasis.opendocument.text-web"},
        {"sxw","application/vnd.sun.xml.writer"},
        {"stw","application/vnd.sun.xml.writer.template"},
        {"sxc","application/vnd.sun.xml.calc"},
        {"stc","application/vnd.sun.xml.calc.template"},
        {"sxd","application/vnd.sun.xml.draw"},
        {"std","application/vnd.sun.xml.draw.template"},
        {"sxi","application/vnd.sun.xml.impress"},
        {"sti","application/vnd.sun.xml.impress.template"},
        {"sxg","application/vnd.sun.xml.writer.global"},
        {"sxm","application/vnd.sun.xml.math"},
        {"sis","application/vnd.symbian.install"},
        {"wbxml","application/vnd.wap.wbxml"},
        {"wmlc","application/vnd.wap.wmlc"},
        {"wmlsc","application/vnd.wap.wmlscriptc"},
        {"bcpio","application/x-bcpio"},
        {"torrent","application/x-bittorrent"},
        //{"bz2","application/x-bzip2"},
        {"vcd","application/x-cdlink"},
        {"pgn","application/x-chess-pgn"},
        {"cpio","application/x-cpio"},
        {"csh","application/x-csh"},
        {"dvi","application/x-dvi"},
        {"spl","application/x-futuresplash"},
        //{"gtar","application/x-gtar"},
        {"hdf","application/x-hdf"},
        {"jar","application/java-archive"},
        {"jnlp","application/x-java-jnlp-file"},
        {"js","application/javascript"},
        {"json","application/json"},
        {"ksp","application/x-kspread"},
        {"chrt","application/x-kchart"},
        {"kil","application/x-killustrator"},
        {"latex","application/x-latex"},
        {"rpm","application/x-rpm"},
        {"sh","application/x-sh"},
        {"shar","application/x-shar"},
        {"swf","application/x-shockwave-flash"},
        {"sit","application/x-stuffit"},
        {"sv4cpio","application/x-sv4cpio"},
        {"sv4crc","application/x-sv4crc"},
        //{"tar","application/x-tar"},
        {"tcl","application/x-tcl"},
        {"tex","application/x-tex"},
        {"man","application/x-troff-man"},
        {"me","application/x-troff-me"},
        {"ms","application/x-troff-ms"},
        {"ustar","application/x-ustar"},
        {"src","application/x-wais-source"},
        //{"zip","application/zip"},
        {"m3u","audio/x-mpegurl"},
        {"ra","audio/x-pn-realaudio"},
        {"wav","audio/x-wav"},
        {"wma","audio/x-ms-wma"},
        {"wax","audio/x-ms-wax"},
        {"pdb","chemical/x-pdb"},
        {"xyz","chemical/x-xyz"},
        {"bmp","image/bmp"},
        {"gif","image/gif"},
        {"ief","image/ief"},
        {"png","image/jpg"},//{"image/png"},
        {"wbmp","image/vnd.wap.wbmp"},
        {"ras","image/x-cmu-raster"},
        {"pnm","image/x-portable-anymap"},
        {"pbm","image/x-portable-bitmap"},
        {"pgm","image/x-portable-graymap"},
        {"ppm","image/x-portable-pixmap"},
        {"rgb","image/x-rgb"},
        {"xbm","image/x-xbitmap"},
        {"xpm","image/x-xpixmap"},
        {"xwd","image/x-xwindowdump"},
        {"css","text/css"},
        {"rtx","text/richtext"},
        {"tsv","text/tab-separated-values"},
        {"jad","text/vnd.sun.j2me.app-descriptor"},
        {"wml","text/vnd.wap.wml"},
        {"wmls","text/vnd.wap.wmlscript"},
        {"etx","text/x-setext"},
        {"mxu","video/vnd.mpegurl"},
        {"flv","video/x-flv"},
        {"wm","video/x-ms-wm"},
        {"wmv","video/x-ms-wmv"},
        {"wmx","video/x-ms-wmx"},
        {"wvx","video/x-ms-wvx"},
        {"avi","video/x-msvideo"},
        {"movie","video/x-sgi-movie"},
        {"ice","x-conference/x-cooltalk"},
        {"3gp","video/3gpp"},
        {"ai","application/postscript"},
        {"aif","audio/x-aiff"},
        {"aifc","audio/x-aiff"},
        {"aiff","audio/x-aiff"},
        {"asc","text/plain"},
        {"atom","application/atom+xml"},
        {"au","audio/basic"},
        {"bin","application/octet-stream"},
        {"cdf","application/x-netcdf"},
        {"cgm","image/cgm"},
        {"class","application/octet-stream"},
        {"dcr","application/x-director"},
        {"dif","video/x-dv"},
        {"dir","application/x-director"},
        {"djv","image/vnd.djvu"},
        {"djvu","image/vnd.djvu"},
        {"dll","application/octet-stream"},
        {"dmg","application/octet-stream"},
        {"dms","application/octet-stream"},
        {"dtd","application/xml-dtd"},
        {"dv","video/x-dv"},
        {"dxr","application/x-director"},
        {"eps","application/postscript"},
        {"exe","application/octet-stream"},
        {"ez","application/andrew-inset"},
        {"gram","application/srgs"},
        {"grxml","application/srgs+xml"},
        //{"gz","application/x-gzip"},
        {"htm","text/html"},
        {"html","text/html"},
        {"ico","image/x-icon"},
        {"ics","text/calendar"},
        {"ifb","text/calendar"},
        {"iges","model/iges"},
        {"igs","model/iges"},
        {"jp2","image/jp2"},
        {"jpe","image/jpg"},//{"image/jpeg"},
        {"jpeg","image/jpg"},//{"image/jpeg"},
        {"jpg","image/jpg"},//{"image/jpeg"},
        {"kar","audio/midi"},
        {"lha","application/octet-stream"},
        {"lzh","application/octet-stream"},
        {"m4a","audio/mp4a-latm"},
        {"m4p","audio/mp4a-latm"},
        {"m4u","video/vnd.mpegurl"},
        {"m4v","video/x-m4v"},
        {"mac","image/x-macpaint"},
        {"mathml","application/mathml+xml"},
        {"mesh","model/mesh"},
        {"mid","audio/midi"},
        {"midi","audio/midi"},
        {"mov","video/quicktime"},
        {"mp2","audio/mpeg"},
        {"mp3","audio/mpeg"},
        {"mp4","video/mp4"},
        {"mpe","video/mpeg"},
        {"mpeg","video/mpeg"},
        {"mpg","video/mpeg"},
        {"mpga","audio/mpeg"},
        {"msh","model/mesh"},
        {"nc","application/x-netcdf"},
        {"oda","application/oda"},
        {"ogv","video/ogv"},
        {"pct","image/pict"},
        {"pic","image/pict"},
        {"pict","image/pict"},
        {"pnt","image/x-macpaint"},
        {"pntg","image/x-macpaint"},
        {"ps","application/postscript"},
        {"qt","video/quicktime"},
        {"qti","image/x-quicktime"},
        {"qtif","image/x-quicktime"},
        {"ram","audio/x-pn-realaudio"},
        {"rdf","application/rdf+xml"},
        {"rm","application/vnd.rn-realmedia"},
        {"roff","application/x-troff"},
        {"sgm","text/sgml"},
        {"sgml","text/sgml"},
        {"silo","model/mesh"},
        {"skd","application/x-koan"},
        {"skm","application/x-koan"},
        {"skp","application/x-koan"},
        {"skt","application/x-koan"},
        {"smi","application/smil"},
        {"smil","application/smil"},
        {"snd","audio/basic"},
        {"so","application/octet-stream"},
        {"svg","image/svg+xml"},
        {"t","application/x-troff"},
        {"texi","application/x-texinfo"},
        {"texinfo","application/x-texinfo"},
        {"tif","image/tiff"},
        {"tiff","image/tiff"},
        {"tr","application/x-troff"},
        {"txt","text/plain"},
        {"vrml","model/vrml"},
        {"vxml","application/voicexml+xml"},
        {"webm","video/webm"},
        {"webp","image/webp"},
        {"wrl","model/vrml"},
        {"xht","application/xhtml+xml"},
        {"xhtml","application/xhtml+xml"},
        {"xml","application/xml"},
        {"xsl","application/xml"},
        {"xslt","application/xslt+xml"},
        {"xul","application/vnd.mozilla.xul+xml"},
            };
            if (dictionary.ContainsKey(filenameExtension))
            {
                return dictionary[filenameExtension];
            }else
            {
                return "application/octet-stream"; //二进制流，未知的文件类型或只能用于下载的文件类型
            }
        }


        /// <summary>
        /// 读取本地文件内容
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="encodingName"></param>
        /// <returns></returns>
        public static string ReadFile(string filePath, string encodingName = "UTF-8")//读取本地文件内容
        {
            string fileContent;
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            if (!File.Exists(filePath))
            {
                throw new Exception("文件" + filePath + "不存在！");
            }
            FileStream fs = null;
            StreamReader streamReader = null;
            try
            {
                Encoding encoding = Encoding.GetEncoding(encodingName);
                fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
                streamReader = new StreamReader(fs, encoding);
                fileContent = streamReader.ReadToEnd();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (streamReader != null)
                    streamReader.Close();//最后记得关闭文件流
                if (fs != null)
                    fs.Close();//最后记得关闭文件流
            }
            return fileContent;
        }

        /// <summary>
        /// 判断文件是否存在
        /// </summary>
        /// <param name="filePath"></param>
        /// <returns></returns>
        public static bool FileIsExists(string filePath)
        {
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            return File.Exists(filePath);
        }

        /// <summary>
        /// 判断目录是否存在
        /// </summary>
        /// <param name="dirPath"></param>
        /// <returns></returns>
        public static bool DirectoryIsExists(string dirPath)
        {
            if (dirPath.IndexOf(":") < 0)
            {
                dirPath = MapPath(dirPath);
            }
            return Directory.Exists(dirPath);
        }


        /// <summary>
        /// 更新文件内容
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="content"></param>
        public static void UpdateFile(string filePath, string content)
        {
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            if (!File.Exists(filePath))
            {
                throw new Exception("文件" + filePath + "不存在!");
                return;
            }
            FileStream fs = null;
            StreamWriter streamWriter = null;
            try
            {
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                fs = new FileStream(filePath, FileMode.Truncate, FileAccess.Write);
                streamWriter = new StreamWriter(fs, encoding);
                streamWriter.Write(content);
                streamWriter.Flush(); //清理缓冲区，将缓冲数据写入文件
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (streamWriter != null)
                    streamWriter.Close();
                if (fs != null)
                    fs.Close();//最后记得关闭文件流
            }
        }

        /// <summary>
        /// 创建文件并写入内容
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="content"></param>
        /// <param name="isOverride">是否覆盖现有文件</param>
        public static void CreateFile(string filePath, string content, bool isOverride = false)
        {
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            if (File.Exists(filePath))
            {
                if (isOverride)
                {
                    UpdateFile(filePath, content);
                }
                else
                {
                    throw new Exception("文件" + filePath + "已经存在!");
                }

            }
            FileStream fs = null;
            StreamWriter streamWriter = null;
            try
            {
                CreateDirectory(filePath.Substring(0, filePath.LastIndexOf("\\")));
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.Write);
                streamWriter = new StreamWriter(fs, encoding);
                streamWriter.Write(content);
                streamWriter.Flush(); //清理缓冲区，将缓冲数据写入文件
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (streamWriter != null)
                    streamWriter.Close();
                if (fs != null)
                    fs.Close();//最后记得关闭文件流
            }
        }

        /// <summary>
        /// 文件中添加内容，采用FileMode.Append方式写入，文件不存在则会创建
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="content"></param>
        public static void AppendFile(string filePath, string content) //写入文件内容
        {
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            if (!File.Exists(filePath))
            {
                CreateFile(filePath, content);
                return;
            }
            FileStream fs = null;
            StreamWriter streamWriter = null;
            try
            {
                CreateDirectory(filePath.Substring(0, filePath.LastIndexOf("\\")));
                Encoding encoding = Encoding.GetEncoding("UTF-8");
                fs = new FileStream(filePath, FileMode.Append, FileAccess.Write);
                streamWriter = new StreamWriter(fs, encoding);
                streamWriter.Write(content);
                streamWriter.Flush(); //清理缓冲区，将缓冲数据写入文件
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                if (streamWriter != null)
                    streamWriter.Close();
                if (fs != null)
                    fs.Close();//最后记得关闭文件流
            }
        }

        /// <summary>
        /// 删除文件
        /// </summary>
        /// <param name="filepath"></param>
        public static void DelFile(string filepath)
        {
            if (string.IsNullOrEmpty(filepath))
            {
                return;
            }
            if (filepath.IndexOf(":") < 0)
            {
                filepath = MapPath(filepath);
            }
            if (File.Exists(filepath))
            {
                File.Delete(filepath);
            }
        }



        /// <summary>
        /// 根据流保存文件，此方法会创建并覆盖同名文件
        /// </summary>
        /// <param name="fileStream"></param>
        /// <param name="savePath"></param>
        public static void SaveFile(Stream fileStream, string savePath)
        {
            Stream saveStream = null;
            try
            {
                savePath = MapPath(savePath);
                string floder = Path.GetDirectoryName(savePath);
                CreateDirectory(floder);
                string fieleName = Path.GetFileName(savePath);
                string[] arrfieleName = fieleName.Split('.');
                if (arrfieleName.Length < 2)
                {
                    throw new Exception("savePath必须是完整的文件名路径");
                }
                using (saveStream = File.Create(savePath))
                {
                    using (fileStream)
                    {
                        byte[] buffer = new byte[8 * 1024];
                        int len;
                        do
                        {
                            len = fileStream.Read(buffer, 0, buffer.Length);
                            if (len > 0)
                            {
                                saveStream.Write(buffer, 0, len);
                                saveStream.Flush();
                            }
                        }
                        while (len > 0);
                    }
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
            finally
            {
                fileStream.Close();
                if (saveStream != null)
                {
                    saveStream.Close();
                }
            }
        }

        /// <summary>
        /// 拷贝文件
        /// </summary>
        /// <param name="source">源文件路径</param>
        /// <param name="destination">目标文件路径</param>
        public static void CopyFile(string source, string destination) //拷贝文件
        {
            if (source.IndexOf(":") < 0)
            {
                source = MapPath(source);
            }
            if (destination.IndexOf(":") < 0)
            {
                destination = MapPath(destination);
            }
            if (File.Exists(source))
            {
                CreateDirectory(destination.Substring(0, destination.LastIndexOf("\\")));
                File.Copy(source, destination, true);
            }
        }


        /// <summary>
        /// 移动文件
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="targetPath"></param>
        /// <returns></returns>
        public static bool MoveFile(string filePath, string targetPath)
        {
            if (string.IsNullOrEmpty(filePath) || string.IsNullOrEmpty(targetPath))
            {
                return false;
            }
            if (filePath.IndexOf(":") < 0)
            {
                filePath = MapPath(filePath);
            }
            if (targetPath.IndexOf(":") < 0)
            {
                targetPath = MapPath(targetPath);
            }
            if (!File.Exists(filePath))
            {
                throw new Exception("文件不存在!");
            }
            if (File.Exists(targetPath))
            {
                throw new Exception("目标文件已存在!");
            }
            File.Move(filePath, targetPath);
            return true;
        }

        /// <summary>
        /// 创建目录
        /// </summary>
        /// <param name="directoryName"></param>

        public static void CreateDirectory(string directoryName) //创建文件夹
        {
            if (string.IsNullOrEmpty(directoryName))
            {
                return;
            }
            if (directoryName.IndexOf(":") < 0)
            {
                directoryName = MapPath(directoryName);
            }
            if (!Directory.Exists(directoryName))
            {
                try
                {
                    Directory.CreateDirectory(directoryName);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }

            }
        }

        /// <summary>
        /// 移动目录
        /// </summary>
        /// <param name="source">源目录</param>
        /// <param name="destination">目标目录</param>
        public static void MoveDirectory(string source, string destination)
        {
            if (string.IsNullOrEmpty(source) || string.IsNullOrEmpty(destination))
            {
                return;
            }
            if (source.IndexOf(":") < 0)
            {
                source = MapPath(source);
            }
            if (destination.IndexOf(":") < 0)
            {
                destination = MapPath(destination);
            }
            if (Directory.Exists(source))
            {
                try
                {
                    Directory.Move(source, destination);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }
            }
        }

        /// <summary>
        /// 复制文件夹，同时复制文件夹中所有文件夹和文件
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="targetDir"></param>
        /// <param name="delOldDir">是否删除源文件</param>
        public static void CopyDirectory(string dir, string targetDir, bool delOldDir) //复制目录
        {
            if (string.IsNullOrEmpty(dir) || string.IsNullOrEmpty(targetDir))
            {
                return;
            }
            if (dir.IndexOf(":") < 0)
            {
                dir = MapPath(dir);
            }
            if (targetDir.IndexOf(":") < 0)
            {
                targetDir = MapPath(targetDir);
            }
            if (dir == targetDir) { return; }
            if (!Directory.Exists(dir))
            {
                return;
            }
            if (!Directory.Exists(targetDir))
            {
                CreateDirectory(targetDir);
            }

            try
            {
                DirectoryInfo dinfo = new DirectoryInfo(dir);
                string toName;
                foreach (FileSystemInfo f in dinfo.GetFileSystemInfos())
                {
                    //Path.Combine(string a ,string b) 为合并两个字符串
                    toName = Path.Combine(targetDir, f.Name);
                    if (f is FileInfo)//如果是文件就复制
                    {
                        File.Copy(f.FullName, toName, true);//true代表可以覆盖同名文件
                    }
                    else//如果是文件夹就创建文件夹然后复制然后递归复制
                    {
                        if (!Directory.Exists(toName))
                        {
                            Directory.CreateDirectory(toName);
                        }
                        CopyDirectory(f.FullName, toName, false);
                    }
                }
                if (delOldDir)
                {
                    Directory.Delete(dir, true);
                }
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }

        }

        /// <summary>
        /// 删除目录
        /// </summary>
        /// <param name="dir"></param>
        /// <param name="delinfile"></param>
        public static void DelDirectory(string dir, bool delinfile)
        {
            if (string.IsNullOrEmpty(dir))
            {
                return;
            }
            if (dir.IndexOf(":") < 0)
            {
                dir = MapPath(dir);
            }
            if (Directory.Exists(dir))
            {
                try
                {
                    Directory.Delete(dir, delinfile);
                }
                catch (Exception ex)
                {
                    throw new Exception(ex.Message);
                }

            }
        }

        /// <summary>
        /// 下载服务器文件到本地,有安全隐患，可以下载任意格式文件，务必控制好调用端权限。
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="saveName"></param>
        /// <param name="perReadByte">每次读取的字节数</param>
        /// <returns></returns>
        public static TipsInfo Download(string filePath, string saveName = null, int perReadByte = 8192)
        {
            HttpResponse response = HttpContext.Current.Response;
            TipsInfo tipsInfo = new TipsInfo();
            filePath = MapPath(filePath);
            if (FileIsExists(filePath))
            {
                FileStream fs = null;
                byte[] fileBuffer = new byte[perReadByte];//每次读取的字节数
                try
                {
                    using (fs = File.OpenRead(filePath))
                    {
                        response.Clear();
                        response.ClearHeaders();
                        response.AddHeader("Content-Length", fs.Length.ToString());//总长度，不设置没有下载进度
                        response.ContentType = "application/octet-stream";
                        response.AddHeader("Content-Disposition", "attachment;filename=" + saveName);// HttpUtility.UrlEncode(fileName,Encoding.UTF8));
                        int readLength = fs.Read(fileBuffer, 0, fileBuffer.Length);
                        while (readLength > 0 && response.IsClientConnected)//持续传输文件
                        {
                            response.OutputStream.Write(fileBuffer, 0, readLength);//写入到响应的输出流
                            response.Flush();//把缓存输出
                            readLength = fs.Read(fileBuffer, 0, fileBuffer.Length);
                        }
                        //response.Close();//如果没有设置Content-Length，则必须注释掉，否则iis上下载不了文件
                        return tipsInfo;
                    }
                }
                catch (Exception ex)
                {
                    tipsInfo.State = 0;
                    tipsInfo.Msg = ex.Message;
                }
                finally
                {
                    if (fs != null)
                        fs.Close();//最后记得关闭文件流
                }
            }
            else
            {
                tipsInfo.State = 0;
                tipsInfo.Msg = "file does not exist";
            }
            return tipsInfo;
        }

        /// <summary>
        /// 获取目录下所有数据，返回一个DirectoryInfoList类型的IEnumerable,包含Id,FullName,Name,IsFile,Length,CreationTime,UpdateTime
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        public static IEnumerable<DirectoryItemInfo> DirectoryList(string path)
        {
            path = MapPath(path);
            if (!Directory.Exists(path))
            {
                return new List<DirectoryItemInfo>();
            }
            List<DirectoryItemInfo> dataList = new List<DirectoryItemInfo>();
            DirectoryInfo dirInfo = new DirectoryInfo(path);
            int i = 1;
            foreach (var fi in dirInfo.GetFileSystemInfos())
            {
                DirectoryItemInfo directoryInfoList = new DirectoryItemInfo();
                dynamic obj = new ExpandoObject();
                var item = (IDictionary<string, object>)obj;
                directoryInfoList.FileSystemInfo = fi;
                directoryInfoList.Id = i;
                directoryInfoList.Name = fi.Name;
                directoryInfoList.FullName = fi.FullName;
                if (fi is FileInfo)
                {
                    directoryInfoList.Type = 1;
                    directoryInfoList.FileLength = StringHelper.Format<double>((((float)((FileInfo)fi).Length) / (float)1024).ToString("F2"));
                }
                else
                {
                    directoryInfoList.Type = 0;
                    directoryInfoList.FileLength = 0;
                }
                directoryInfoList.CreationTime = fi.CreationTime;
                directoryInfoList.LastWriteTime = fi.LastWriteTime;
                i++;
                dataList.Add(directoryInfoList);
            }
            return dataList;
        }

        /// <summary>
        /// 获取目录权限
        /// </summary>
        /// <param name="dirName"></param>
        /// <returns></returns>
        public static List<FileSystemRights> GetFileSystemRight(string dirName)
        {
            List<FileSystemRights> ret = new List<FileSystemRights>();
            DirectorySecurity dirSec = Directory.GetAccessControl(MapPath(dirName), AccessControlSections.All);
            AuthorizationRuleCollection rules = dirSec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
            foreach (FileSystemAccessRule rule in rules)
            {
                ret.Add(rule.FileSystemRights);
            }
            return ret;
        }
        #endregion

    }
}
